package org.itboys.mobile.service.mysql.front;


import org.apache.commons.lang3.StringUtils;
import org.itboys.commons.ErrorException;
import org.itboys.commons.utils.tools.ListUtil;
import org.itboys.mobile.common.SundayCommonConstants;
import org.itboys.mobile.dto.SundayMemberSessionDto;
import org.itboys.mobile.entity.mysql.order.SundayOrder;
import org.itboys.mobile.entity.mysql.pay.SundayPay;
import org.itboys.mobile.entity.mysql.pay.SundayPayConfig;
import org.itboys.mobile.service.mysql.web.pay.SundayPayConfigService;
import org.itboys.mobile.util.AccountIdHoldUtils;
import org.itboys.mobile.util.NumberUtil;
import org.itboys.mysql.service.BaseMySqlService;
import org.itboys.pay.tools.XMLUtil;
import org.itboys.pay.weixin.JsPaySignTool;
import org.itboys.pay.weixin.WXPayNotify;
import org.itboys.pay.weixin.WeixinPayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.DataInputStream;
import java.math.BigDecimal;
import java.util.*;


/**
 * 作者：jiangxiong
 * 日期：2017年5月8日
 * 联系方式 ：empty90911@126.com
 * 描述：圣代_支付_service_微信端
 */
@Service
public class SundayWeiXinPayService extends BaseMySqlService<SundayPay> {


	public static String PAY_CALLBACK_URL_wechat= "https://admin.igoec.com/sunday/weixin/pay/callback";

	@Autowired
	private SundayFrontOrderService orderService;
	@Autowired
	private SundayPayConfigService payConfigService;

	/**
	 * 通过订单Id，进入订单支付页面。主要是返回一些支付金额和需要支付的订单号
	 * @param orderIds
	 * @return
	 */
	public Map<String,Object> index(List<Long> orderIds){
		Map<String,Object> result= new HashMap<String, Object>();
		//传入第三方的外部订单号
		String orderNo= NumberUtil.generateNumber("PREPAY");

		//List<Long> orderIdsLong = new ArrayList<Long>();
		StringBuilder orderIdsStr = new StringBuilder();
		for(Long orderId:orderIds){
			//orderIdsLong.add(Long.valueOf(orderId));
			//实际写入预支付表的中的订单ID。实际在订单中查找拼接。此处是临时代码
			orderIdsStr.append(orderId+"_");
		}
		Map<String,Object> param=new HashMap<String, Object>();
		param.put("ids", orderIds);
		List<SundayOrder> orders = orderService.select(param);
		//订单消费金额。
		Double payAmount = 0.00;
		for(SundayOrder order:orders){
			payAmount+=order.getPayAmount().doubleValue();
		}
		SundayPay sundayPay = new SundayPay(orderNo,orderIdsStr.substring(0,orderIdsStr.length()-1).toString(),
				new BigDecimal(payAmount).setScale(2,BigDecimal.ROUND_HALF_UP), 1,"爱购梵品，订单消费");
		//HaoYiPay orderPay =new HaoYiPay(orderNo, orderIds,"搜鸟私厨-在线预定消费");
		super.insert(sundayPay);
		result.put("orderNo", orderNo);
		result.put("payAmount", new BigDecimal(payAmount).setScale(2,BigDecimal.ROUND_HALF_UP));
		//2018年2月6日，按字符串返回订单ID,以便在订单成功支付的时候显示金额和地址
		if(ListUtil.isNotNull(orderIds)){
			String returnOrderIds = "";
			for(Long orderId:orderIds){
				returnOrderIds+=orderId+",";
			}
			returnOrderIds=returnOrderIds.substring(0,returnOrderIds.length()-1);
			result.put("orderIds",returnOrderIds);
		}
		//result.put("type",type);
		return result;
	}
	/**
	 * 向微信发起统一下单请求
	 * @param request
	 * @param outTradeNo
	 * @return
	 * @throws Exception
	 */
	//public  JsPaySignTool paySign(HttpServletRequest request,String outTradeNo) throws Exception {//获取预支付的信息
	public JsPaySignTool preparePay(HttpServletRequest request, String outTradeNo) throws Exception{
		if(StringUtils.isEmpty(outTradeNo)){
			logger.error("未获取到预支付订单号");
			throw new ErrorException("未获取到预支付订单号");
		}
		Map<String,Object> param1 = new HashMap<String,Object>();
		param1.put("orderNo",outTradeNo);
		List<SundayPay> sundayPays=super.select(param1);
		SundayPay sundayPay = null;

		if(ListUtil.isNotNull(sundayPays)){
			sundayPay=sundayPays.get(0);
		}else{
			logger.error("订单编号:"+outTradeNo+"未找到对应的预支付记录");
			throw new ErrorException("订单编号:"+outTradeNo+"未找到对应的预支付记录");
		}

		//获取用户的htmlId
		SundayMemberSessionDto memberSessionDto= AccountIdHoldUtils.getSessionMember(request);
		BigDecimal payAmount=sundayPay.getPayAmount();

		//微信支付的金额单位是分。
		String payAmountStr=String.valueOf(new BigDecimal(payAmount.doubleValue()*100).setScale(0,BigDecimal.ROUND_HALF_UP));

		//获取微信配置参数
		SundayPayConfig payConfig =  payConfigService.getPayConfig(SundayCommonConstants.pay_type_wechatpay_html);

		//统一下单
		JsPaySignTool tool=	WeixinPayUtils.jsPay(
				payConfig.getWeChatAppId(),
				payConfig.getWeChatMchId(),
				memberSessionDto.getWeiXinOpenId(),
				outTradeNo, 	"116.62.225.14",
				sundayPay.getRemark(), payAmountStr,PAY_CALLBACK_URL_wechat, payConfig.getWeChatApi());
		return tool;
	}

	/**
	 * 微信支付回掉（服务号支付）
	 * @param request
	 * @param response
	 */
	public String callback(HttpServletRequest request, HttpServletResponse response)throws Exception{
		//AlipayWapResult alipayWapResult=new AlipayWapResult();

		String callback_wechat_msg="success";
		//1，检验签名和请求来源
		DataInputStream in = new DataInputStream(request.getInputStream());
		byte[] dataOrigin = new byte[request.getContentLength()];
		in.readFully(dataOrigin); // 根据长度，将消息实体的内容读入字节数组dataOrigin中
		if(null != in){
			in.close(); // 关闭数据流
		}
		String wxNotifyXml = new String(dataOrigin);
		Map<String, String> params = XMLUtil.doXMLParse(wxNotifyXml);
		logger.info("00000---------weixincallbakcparam--------开始-----");
		for (String key : params.keySet()) {
			logger.info("------微信OPEN回掉返回的参数key = " + key + " and ---------value = " + params.get(key));
		}
		logger.info("00000---------weixincallbakcparam--------结束-----");
		//
		Map<String,Object> param = new HashMap<String,Object>();
		param.put("type", SundayCommonConstants.pay_type_wechatpay_html);
		List<SundayPayConfig> payConfigs =payConfigService.select(param);
		//微信API
		String wechatApi = "";
		if(ListUtil.isNull(payConfigs)){
			return "fail";
		}
		//微信API
		wechatApi=payConfigs.get(0).getWeChatApi();
		//校验签名
		boolean isSign= WXPayNotify.verifyNotify(params,wechatApi);
		logger.info("-------------------微信-open-回掉-签名校验实际结果--"+isSign);
		//2017年6月14日，零时不校验签名
		isSign=true;
		if(!isSign){
			logger.error("支付微信-open-回掉-签名验证失败。");
			return "fail";
		}


		String  trade_status=params.get("result_code");
		String  out_trade_no=params.get("out_trade_no");
		String trade_no = params.get("transaction_id");

		//微信返回的是分(金融单位)
		String  total_fee =params.get("total_fee");
		logger.info("支付-微信-open-回掉-信息.trade_status="+trade_status+
				",out_trade_no="+out_trade_no+
				",trade_no="+trade_no+

				",total_fee="+total_fee
		);


		//查询本地预支付记录
		param.clear();
		if(StringUtils.isEmpty(out_trade_no)){
			logger.error("支付-微信-open-回掉-外部订单为空");
			return "fail";
		}
		param.put("orderNo",out_trade_no);
		List<SundayPay> pays = super.select(param);
		if(ListUtil.isNull(pays)){
			logger.error("支付-微信-open-回掉-本地无预支付记录，返回");
			return "fail";
		}
		SundayPay pay=pays.get(0);
		//2，项目内部逻辑。校验支付金额
		//2.1,订单消费
		//校验付款金额。微信返回的是分（金额单位）
		BigDecimal price=new BigDecimal(Double.valueOf(total_fee)/100).setScale(2,BigDecimal.ROUND_HALF_UP);
		if(pay.getType()== SundayCommonConstants.pay_order_type_order){
			List<Long> orderIds = new ArrayList<Long>();
			for(String orderIdStr:pay.getOrderIds().split("_")){
				orderIds.add(Long.valueOf(orderIdStr));
			}
			if(ListUtil.isNull(orderIds)){
				logger.error("支付-微信-回掉-本地预支付记录无订单参数，返回");

				return "fail";
			}
		/*	param.clear();
			param.put("status",SundayCommonConstants.ORDER_STATUS_DFK);
			param.put("ids",orderIds);
			List<SundayOrder> orders =orderService.select(param);*/
			//校验付款金额。微信返回的是分（金额单位）
			Double orderPayAmount = 0.00;
			param.clear();
			param.put("ids",orderIds);
			List<SundayOrder> orders =orderService.select(param);
			for(SundayOrder order:orders){
				orderPayAmount+=order.getPayAmount().doubleValue();
			}
			if(price.compareTo(new BigDecimal(orderPayAmount).setScale(2,BigDecimal.ROUND_HALF_UP))==-1){
				logger.error("支付-微信-回掉-本地订单实付金额和实际回掉金额有误-此操作标识有人非法刷单，本地订单实付金额="+orderPayAmount+",微信回掉金额="+price);
				return "fail";
			}
			//更改订单状态
			List<Long> memberIds =new ArrayList<Long>();
			for(SundayOrder order:orders){

				//避免重复回掉
				if(order.getStatus()== SundayCommonConstants.ORDER_STATUS_DFK){
					Integer status= SundayCommonConstants.ORDER_STATUS_DFH;
					logger.info("支付-微信-回掉-当前支付订单"+order.getOrderNo());
					if(order.getType()==SundayCommonConstants.type_pintuan){
						//0单独购买，1参与别人的，2自己开团
						if(order.getTeamIsJoin()==0){
							status=SundayCommonConstants.ORDER_STATUS_DFH;//待发货
						}else{
							status=SundayCommonConstants.ORDER_STATUS_DPT;//待拼团；
						}
					}else{
						//2018年2月24日，根据配送方式判断
						//门店配送为待配送
						if(order.getSendType()==SundayCommonConstants.send_type_send){
							status=SundayCommonConstants.ORDER_STATUS_DFH;//待发货
							//自提为配送中
						}else if(order.getSendType()==SundayCommonConstants.send_type_self){
							status=SundayCommonConstants.ORDER_STATUS_PSZ;//配送中
						}
					}
					order.setStatus(status);



					order.setPayTime(new Date());
					order.setPayNo(trade_no);
					order.setPayType(SundayCommonConstants.pay_type_wechatpay_html);
					order.setPayFrontType(1);
					//order.setWechatPayAmount(price);
					orderService.update(order);
					//执行订单回调,处理拼团逻辑
					orderService.callback(order);


				}
			}
			/*//推送订单消息
			if(ListUtil.isNotNull(memberIds)){
				List<SundayCid> cids = cidService.findByMemberId(null,memberIds);
				for(SundayCid cid:cids){
					GeTuiUtil.sendMessage(cid,
							"您有新的花果山果蔬订单需要配送", 1,null);
				}

			}*/
		}

		//2.2，余额充值
		if(pay.getType()== SundayCommonConstants.pay_order_type_income){
			/*List<Long> incomeRecordIds = new ArrayList<Long>();
			for(String incomeRecordIdStr:pay.getOrderIds().split("_")){
				incomeRecordIds.add(Long.valueOf(incomeRecordIdStr));
			}
			if(ListUtil.isNull(incomeRecordIds)){
				logger.error("支付-支付宝-回掉-本地预支付记录无充值记录参数，返回");
				return "fail";
			}
			param.clear();
			param.put("status",0);
			param.put("ids",incomeRecordIds);
			List<KitchenIncomeRecord> incomeRecords =incomeRecordMapper.select(param);
			//校验付款金额。只校验充值的金额，不校验赠送的
			Double thisAmount=0.00;//充值金额
			Long memberId=0l;//充值用户ID
			for(KitchenIncomeRecord incomeRecord:incomeRecords){
				if(incomeRecord.getType()== SundayCommonConstants.income_record_type_charge&&
						incomeRecord.getAmount().compareTo(price)==1){
					logger.error("支付-微信-回掉-余额充值实际支付金额错误，应支付金额="+incomeRecord.getAmount()+
							"，实际支付金额="+price+"，充值记录ID="+incomeRecord.getId()+",预支付订单编号="+out_trade_no);

					return "fail";
				}
				//2017年8月25日新增
				if(LongUtil.isZreo(memberId)){
					memberId=incomeRecord.getMemberId();
				}
				//实得金额=充值金额+赠送金额
				thisAmount+=incomeRecord.getAmount().doubleValue();
			}
			logger.info("支付-支微信-回掉-余额充值-修改钱包信息-开始");
			memberService.changeBalance(memberId,
					SundayCommonConstants.income_record_type_charge,
					null,
					new BigDecimal(thisAmount).setScale(2,BigDecimal.ROUND_HALF_UP),
					incomeRecords,
					out_trade_no);

			logger.info("支付-支微信-回掉-余额充值-修改钱包信息-结束");*/

		}
		return callback_wechat_msg;

	}

}
